package com.ibm.cloud.envcheck.kit;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.ibm.cloud.envcheck.bean.CheckItem;
import com.ibm.cloud.envcheck.bean.ConfigBean;
import com.ibm.json.java.JSONArray;
import com.ibm.json.java.JSONObject;

/**
 * Read topology from user.
 * 
 * @author macky
 *
 */
public class ConfigKit {
	
	public static void main(String[]args){
		List<File>files = scanConfigFiles(args);
		for(File file:files){
			System.out.println(file.getName());
		}
	}
	
	public static List<File> scanConfigFiles(String[]args){
		List<File>configFiles = null;
		if(args==null){
			//scan default.
			print("No configuration file was specified,System will scan default folder "+
					PathKit.getRootClassPath()+"/config,please wait...");
			configFiles = getConfigFiles(null);
			return configFiles;
		}else{
			configFiles = getConfigFiles(args);
			if(configFiles==null||configFiles.isEmpty()){
				print("Please specify valid configuration file or files");
				System.exit(0);
			}
			return configFiles;
		}
	}
	
	private static void print(String str){
		System.out.println(str);
	}
	
	private static List<File> getConfigFiles(String pathList[]){
		if(pathList==null || pathList.length==0){
			// it means that user haven't specified any config file.
			// we need to scan default folder.
			String rootPath = PathKit.getRootClassPath();
			List<File>fileList = new ArrayList<File>();
			setConfigFile(new File(rootPath+File.separator+"config"),fileList);
			return fileList;
		}else{
			// user specified some configuration files
			List<File>fileList = new ArrayList<File>();
			for(String path:pathList){
				File file = new File(path);
				if(!file.exists()||file.isDirectory()){
					return null;
				}else{
					fileList.add(file);
				}
			}
			return fileList;
		}
	}

	private static void setConfigFile(File file,List<File>fileList) {
		if (file != null) {
			if (file.isDirectory()) {
				File[] fileArray = file.listFiles();
				if (fileArray != null) {
					for (int i = 0; i < fileArray.length; i++) {
						setConfigFile(fileArray[i],fileList);
					}
				}
			} else {
				if(file.getName().endsWith(".conf")){
					fileList.add(file);
				}
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	public static ConfigBean readConfig(InputStream in){
		try{
			JSONObject jsonObj = JSONObject.parse(in);
			JSONObject paramsObj = (JSONObject) jsonObj.get("params");
			ConfigBean configBean = new ConfigBean();
			configBean.setHost((String)paramsObj.get("host"));
			//configBean.setResultStorePath((String)paramsObj.get("result_store_path"));
			configBean.setOsAdmin((String)paramsObj.get("os_admin"));
			configBean.setPassword((String)paramsObj.get("os_password"));
			Object port = paramsObj.get("port");
			if(port==null){
				//do nothing, the port will be set to default 22
			}else{
				configBean.setPort(new Integer((String) port));
			}
			JSONArray checkList = (JSONArray)paramsObj.get("check-list");
			for(Object obj:checkList){
				JSONObject itemObj = (JSONObject)obj;
				CheckItem item = new CheckItem();
				item.setCheckType((String)itemObj.get("type"));
				item.setResultStorePath((String)itemObj.get("result_store_path"));
				JSONObject inputObj = (JSONObject)itemObj.get("input");
				item.setRemoteFilePath(wrapProperty(inputObj,"remote_file_path"));
				item.setCommandLine(wrapProperty(inputObj,"command-line"));
				Object allPropertyObj = inputObj.get("need_check_params");
				if(allPropertyObj!=null){
					JSONObject checkParams = (JSONObject)allPropertyObj;
					Set<String> keys = checkParams.keySet();
					Iterator<String> keyIterator = keys.iterator();
					while(keyIterator.hasNext()){
						String key = keyIterator.next();
						String value = (String)checkParams.get(key);
						item.addNeedCheckParams(key, value);
					}
					
				}
				configBean.getItems().add(item);
			}
			return configBean;
		}catch(IOException e){
			e.printStackTrace();
		}
		
		return null;
	}
	
	public static ConfigBean readConfig(String configPath){
		if(configPath == null){
			return null;
		}
		try {
			InputStream in = new FileInputStream(configPath);
			return readConfig(in);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	public static ConfigBean readConfig(File file){
		if(file==null||file.isDirectory()){
			return null;
		}
		try {
			InputStream in = new FileInputStream(file);
			return readConfig(in);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static ConfigBean readConfigFromStr(String str){
		
		return null;
	}
	
	private static String wrapProperty(JSONObject obj,String key){
		if(obj==null||key==null){
			return "";
		}
		
		Object value = obj.get(key);
		if(value==null){
			return "";
		}
		return (String)(obj.get(key));
	}
}
